#include "ethernet.h"
#include "utils.h"
#include "driver.h"
#include "arp.h"
#include "ip.h"


/**
 * @brief 处理一个收到的数据包
 * 
 * @param buf 要处理的数据包
 */
void ethernet_in(buf_t *buf)
{
    // TO-DO
    int l = sizeof(ether_hdr_t);
    if(buf->len < l){
        printf("\nethernet_in: len(buf) < size(ether_hdr)\n");
        return ;
    }
    // 提取出源的mac地址
    ether_hdr_t *hdr = (ether_hdr_t *)buf->data;
    uint8_t srcMac[NET_MAC_LEN];
    memcpy(srcMac, hdr->src, NET_MAC_LEN);
    // 提取出协议
    uint16_t protocol = hdr->protocol16;
    protocol = swap16(protocol); // 记得大小端变化
    // 向上层传递数据包
    if(buf_remove_header(buf, l) == 0){
        net_in(buf, protocol, srcMac);
    }else{
        printf("\nethernet_in: buf_remove_header error\n");
    }
}
/**
 * @brief 处理一个要发送的数据包
 * 
 * @param buf 要处理的数据包
 * @param mac 目标MAC地址
 * @param protocol 上层协议
 */
void ethernet_out(buf_t *buf, const uint8_t *mac, net_protocol_t protocol)
{
    // TO-DO
    if(buf->len < 46){
        buf_add_padding(buf, ETHERNET_MIN_TRANSPORT_UNIT - buf->len);
    }
    // 添加以太网包头
    buf_add_header(buf, sizeof(ether_hdr_t));
    ether_hdr_t *hdr = (ether_hdr_t *)buf->data;
    // 填写目的mac地址
    memcpy(hdr->dst, mac, NET_MAC_LEN);
    // 填写源MAC地址
    memcpy(hdr->src, net_if_mac, NET_MAC_LEN);
    // 填写协议类型
    hdr->protocol16 = swap16((uint16_t) protocol);
    // 发送到驱动层
    driver_send(buf);
}
/**
 * @brief 初始化以太网协议
 * 
 */
void ethernet_init()
{
    buf_init(&rxbuf, ETHERNET_MAX_TRANSPORT_UNIT + sizeof(ether_hdr_t));
}

/**
 * @brief 一次以太网轮询
 * 
 */
void ethernet_poll()
{
    if (driver_recv(&rxbuf) > 0)
        ethernet_in(&rxbuf);
}
